﻿#region ディレクティブを使用する

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;

#endregion

namespace SmartPDA.WMDevice
{

	public sealed class PlatformInfo
	{

		/// <summary>
		/// デバイスプラットフォーム列挙
		/// </summary>
		public enum Platform
		{
			/// <summary>
			/// WindowsCE
			/// </summary>
			WindowsCE,

			/// <summary>
			/// PocketPC
			/// </summary>
			PocketPC,

			/// <summary>
			/// Smartphone
			/// </summary>
			Smartphone
		}

		/// <summary>
		/// デバイスの OS Edition 列挙
		/// </summary>
		public enum OSEdition
		{
			Unknown, PPC2000, PPC2002, PPC2003, PPC2003SE, WM2005, WM2006
		}

		#region P/Invoke

		private const uint SPI_GETPLATFORMTYPE = 257;
		private const uint SPI_GETOEMINFO = 258;

		[DllImport("CoreDll.dll")]
		internal static extern bool SystemParametersInfo(uint uiAction, uint uiParam, byte[] pvParam, uint fWinIni);

		[DllImport("CoreDll.dll")]
		internal static extern bool SystemParametersInfo(uint uiAction, uint uiParam, StringBuilder pvParam, uint fWinIni);

		#endregion

		/// <summary>
		/// デバイスのプラットフォーム情報を返します
		/// </summary>
		/// <returns>Platform 列挙子</returns>
		/// <example><code>
		/// Console.WriteLine( SmartPDA.WMDevice.HWCtrl.GetPlatform().ToString() );
		/// </code></example>
		/// <seealso cref="Platform"/>
		/// <see>http://www.dotnet247.com/247reference/msgs/40/203699.aspx</see>
		public static Platform GetPlatform()
		{
			Platform plat = Platform.WindowsCE;

			StringBuilder strbuild = new StringBuilder(200);
			SystemParametersInfo(SPI_GETPLATFORMTYPE, 200, strbuild, 0);

			string str = strbuild.ToString();

			switch (str)
			{
				case "PocketPC":
					plat = Platform.PocketPC;
					break;
				case "SmartPhone":
					// Note that the strbuild parameter from the
					// PInvoke returns "SmartPhone" with an
					// upper case P. The correct casing is
					// "Smartphone" with a lower case p.
					plat = Platform.Smartphone;
					break;
			}
			return plat;
		}

		/// <summary>
		/// 実行しているデバイスのプラットフォームのエディションの OSEdtion 列挙子を返します
		/// </summary>
		/// <param name="plat">Platform 列挙子。通常 GetPlatform の戻り値を指定します。</param>
		/// <example><code>
		/// Console.WriteLine( SmartPDA.WMDevice.HWCtrl.GetPlatformEdition( SmartPDA.WMDevice.HWCtrl.GetPlatform() ) );
		/// </code></example>
		/// <returns>プラットフォームの OSEdition 列挙子</returns>
		public static OSEdition GetPlatformEdition(Platform plat)
		{

			// PocketPC2000, PocketPC2002
			if (System.Environment.OSVersion.Version.Major == 3)
			{
				if (plat == Platform.PocketPC || plat == Platform.Smartphone)
				{
					return OSEdition.PPC2002;
				}
				return OSEdition.PPC2000;
			}

			// PocketPC2003, PocketPC2003SE
			if (System.Environment.OSVersion.Version.Major == 4)
			{
				if (System.Environment.OSVersion.Version.Minor > 20)
				{
					return OSEdition.PPC2003SE;
				}
				return OSEdition.PPC2003;
			}

			// Windows Mobile 5.0 OS 5.1.195
			// Windows Mobile 6.0 Classic : OS 5.2.318 ( Build 15342.0.0.0 )
			if (System.Environment.OSVersion.Version.Major == 5)
			{

				if (System.Environment.OSVersion.Version.Minor > 1)
				{
					return OSEdition.WM2006;
				}

				return OSEdition.WM2005;
			}

			return OSEdition.Unknown;
		}

		/// <summary>
		/// デバイスの OEM 名を文字列で返します。
		/// </summary>
		/// <returns>返される OEM 名は、通常メーカ名と機種名で構成されている文字列です。</returns>
		/// <example><code>
		/// string OEMInfo = SmartPDA.WMDevice.GetOEMInfo();
		/// </code></example>
		public static string GetOEMInfo()
		{
			byte[] outBuffer = new byte[128];
			int outBufferSize = outBuffer.Length;

			BitConverter.GetBytes(outBufferSize).CopyTo(outBuffer, 0);

			try
			{
				SystemParametersInfo(SPI_GETOEMINFO, (uint)outBufferSize, outBuffer, 0);
			}
			catch
			{
				return "";
			}

			return Encoding.Unicode.GetString(outBuffer, 0, outBufferSize).ToString().Replace("\0", "");

		}

	}
}
